package com.quanyan.ic.common.http;

import com.alibaba.fastjson.JSON;
import com.quanyan.ic.common.http.enums.ApiResponseEnum;
import com.quanyan.ic.common.http.enums.BaseEnum;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Date;

public class APIResponse<T> implements Serializable {

    private static final long serialVersionUID = 5241526151768786394L;

    private final String ver = "1.1.0000";
    private boolean ret;
    private String errmsg = "";
    private int errcode;
    private T data;
    private String sign = "";
    private Long serverTime;//服务器时间

    public APIResponse() {
    }

    private APIResponse(ApiResponseEnum apiResponseEnum) {
        this.setApiResponseEnum(apiResponseEnum);
    }

    private APIResponse(BaseEnum baseEnum, T t) {
        this.setApiResponseEnum(baseEnum);
        this.data = t;
    }

    public static <T> APIResponse<T> returnSuccess() {
        return new APIResponse(ApiResponseEnum.SUCCESS);
    }

    public static <T> APIResponse<T> returnSuccess(T data) {
        return new APIResponse(ApiResponseEnum.SUCCESS, data);
    }

    public static <T> APIResponse<T> returnSuccess(T data, BaseEnum baseEnum) {
        APIResponse apiResponse = new APIResponse(baseEnum, data);
        apiResponse.setRet(true);
        return apiResponse;
    }

    public static <T> APIResponse<T> returnFail(BaseEnum baseEnum) {
        APIResponse apiResponse = new APIResponse();
        apiResponse.ret = false;
        apiResponse.errmsg = baseEnum.getLabel();
        apiResponse.errcode = baseEnum.getId();
        apiResponse.serverTime = System.currentTimeMillis();
        return apiResponse;
    }

    public static <T> APIResponse<T> returnFail(String msg) {
        APIResponse apiResponse = new APIResponse();
        apiResponse.ret = false;
        apiResponse.errmsg = msg;
        apiResponse.errcode = ApiResponseEnum.FAIL.getId();
        apiResponse.serverTime = System.currentTimeMillis();
        return apiResponse;
    }

    public static <T> APIResponse<T> returnFail(T data, BaseEnum baseEnum) {
        APIResponse apiResponse = returnSuccess(data, baseEnum);
        apiResponse.setRet(false);
        return apiResponse;
    }

    public static <T> APIResponse<T> returnFail(int errorCode, String errorMessage) {
        APIResponse apiResponse = new APIResponse();
        apiResponse.errcode = errorCode;
        apiResponse.errmsg = errorMessage;
        apiResponse.ret = false;
        apiResponse.serverTime = System.currentTimeMillis();
        return apiResponse;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public Long getServerTime() {
        return serverTime;
    }

    public void setServerTime(Long serverTime) {
        this.serverTime = new Date().getTime();
    }

    public String getVer() {
        return ver;
    }

    public boolean isRet() {
        return ret;
    }

    public void setRet(boolean ret) {
        this.ret = ret;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    public String getErrmsg() {
        return StringUtils.defaultIfEmpty(errmsg, StringUtils.EMPTY);
    }

    public void setErrcode(int errcode) {
        this.errcode = errcode;
    }

    public int getErrcode() {
        return errcode;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    private void setApiResponseEnum(BaseEnum baseEnum) {
        this.ret = baseEnum.isSuccess();
        this.errcode = baseEnum.getId();
        this.errmsg = baseEnum.getLabel();
        this.serverTime = new Date().getTime();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((data == null) ? 0 : data.hashCode());
        result = prime * result + ((StringUtils.isEmpty(errmsg)) ? 0 : errmsg.hashCode());
        result = prime * result + (ret ? 1231 : 1237);
        result = prime * result + errcode;
        result = prime * result + ((ver == null) ? 0 : ver.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        APIResponse<?> that = (APIResponse<?>) o;
        if (errcode != that.errcode) {
            return false;
        }
        if (ret != that.ret) {
            return false;
        }
        if (data != null ? !data.equals(that.data) : that.data != null) {
            return false;
        }
        if (errmsg != null ? !errmsg.equals(that.errmsg) : that.errmsg != null) {
            return false;
        }
        return !(ver != null ? !ver.equals(that.ver) : that.ver != null);
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }

}
